from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
import torch
from torch import nn
# auto gradient
from torch.autograd import Variable

data = load_breast_cancer()
x, y = data.data, data.target
y = y.reshape(-1, 1)

x_train, x_test, y_train, y_test = train_test_split(x, y)

# 将x,y 编程tensor类型
x_train = Variable(torch.tensor(x_train, dtype=torch.float32))
x_test = Variable(torch.tensor(x_test, dtype=torch.float32))
y_train = Variable(torch.tensor(y_train, dtype=torch.float32))
y_test = Variable(torch.tensor(y_test, dtype=torch.float32))

# 创建模型
l1 = nn.Linear(30, 10)
act = nn.Sigmoid()
l2 = nn.Linear(10, 1)
model = nn.Sequential(l1, act, l2, act)

# 优化器和代价函数
loss = nn.BCELoss()  #BCE: binary cross entropy
opt = torch.optim.SGD(model.parameters(), lr=0.008) # 参数，学习率

#训练模型
for i in range(5001):
    opt.zero_grad()
    # 正向传播
    y_ = model(x_train)
    l = loss(y_, y_train)
    # 反向传播
    l.backward()
    opt.step()
    if i % 100 == 0 :
        print(l.data.numpy())

# 二分类准确率
y_ = model(x_test) # 测试集结果（概率）
pro = (y_.data.numpy() > 0.5) # 预测的类别
y_true = y_test.data.numpy() # 真实类别
print((pro==y_true).mean())
